cmake_minimum_required(VERSION 3.5)

project(kacanopen C CXX)
find_package(rosidl_default_generators REQUIRED)
find_package(ament_cmake REQUIRED)

### dependencies ###

find_package(Threads)
find_package(Boost 1.46.1 COMPONENTS system filesystem REQUIRED)

### constants ###

#add_definitions("-DSDO_RESPONSE_TIMEOUT_MS=${SDO_RESPONSE_TIMEOUT_MS}")
#add_definitions("-DBUSNAME=\"${BUSNAME}\"")
#add_definitions("-DBAUDRATE=${BAUDRATE}")
#add_definitions("-DCONSECUTIVE_SEND_PAUSE_MS=${CONSECUTIVE_SEND_PAUSE_MS}")

add_definitions("-DSHARE_INSTALLED_PATH=\"/share/${PROJECT_NAME}/config\"")

rosidl_generate_interfaces(
    ${PROJECT_NAME}
        ros_bridge/srv/Mode.srv
        ros_bridge/srv/Action.srv
    DEPENDENCIES      
)

### includes ###

include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${rclcpp_INCLUDE_DIRS} )

include_directories(${CMAKE_CURRENT_LIST_DIR}/core/include)
include_directories(${CMAKE_CURRENT_LIST_DIR}/master/include)
include_directories(${CMAKE_CURRENT_LIST_DIR}/ros_bridge/include)
include_directories(${CMAKE_CURRENT_LIST_DIR}/apps/include)

### Compiler config ###

# Use g++-4.9 if there is also an older g++ version on the system
if("${CMAKE_CXX_COMPILER}" STREQUAL "" OR "${CMAKE_CXX_COMPILER}" STREQUAL "gcc" OR "${CMAKE_CXX_COMPILER}" STREQUAL "g++")
	find_program(NEWER_GNU_CXX_COMPILER g++-4.9)
	if (NOT "${NEWER_GNU_CXX_COMPILER}" STREQUAL "")
		set(CMAKE_CXX_COMPILER ${NEWER_GNU_CXX_COMPILER})
		message("Using ${CMAKE_CXX_COMPILER} as compiler.")
	endif()
endif()

if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "")
	if("${CMAKE_CXX_COMPILER}" MATCHES ".*g[+][+].*")
		set(CMAKE_CXX_COMPILER_ID "GNU")
	endif()
endif()

if("${CMAKE_CXX_COMPILER_VERSION}" STREQUAL "")
	if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
		execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version COMMAND head -1 COMMAND awk "{ print $NF }" OUTPUT_VARIABLE CMAKE_CXX_COMPILER_VERSION)
	elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
		message(FATAL_ERROR "Setting CMAKE_CXX_COMPILER_ID not implemented.")
	endif()
endif()

# GCC ist not supported until 4.9
# Clang ist not supported until 3.6
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
	if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)
		message(FATAL_ERROR "GCC version must be at least 4.9. Earlier versions miss std::regex support.")
	endif()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
	if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.6)
		message(FATAL_ERROR "Clang version must be at least 3.6! Earlier versions don't support debug information for auto.")
	endif()
else()
	message(FATAL_ERROR "You are using an unsupported compiler! Compilation has only been tested with Clang and GCC.")
endif()

SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -Wextra") # -Werror
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra") # -Werror

### settings ###

include(CMakeSettings.txt)

add_definitions("-DSDO_RESPONSE_TIMEOUT_MS=${SDO_RESPONSE_TIMEOUT_MS}")
add_definitions("-DBUSNAME=\"${BUSNAME}\"")
add_definitions("-DBAUDRATE=${BAUDRATE}")
add_definitions("-DCONSECUTIVE_SEND_PAUSE_MS=${CONSECUTIVE_SEND_PAUSE_MS}")

## Driver begin ##

if (DEFINED CAN_DRIVER_NAME)
	set(DRIVER "${CAN_DRIVER_NAME}")
	message(WARNING "CAN_DRIVER_NAME is deprecated. Use DRIVER instead. Overwriting DRIVER with CAN_DRIVER_NAME (${CAN_DRIVER_NAME}) now...")
endif()

foreach(BUILD_DRIVER ${BUILD_DRIVERS})
	# TODO: Replace with CMake 3.3 command IN_LIST
	list(FIND SUPPORTED_DRIVERS "${BUILD_DRIVER}" supported)
	if (${supported} EQUAL -1)
		message(FATAL_ERROR "Driver ${BUILD_DRIVER} does not exist, but you've specified it in BUILD_DRIVERS.")
	endif()
endforeach()

list(FIND SUPPORTED_DRIVERS "${DRIVER}" driver_supported)
if (${driver_supported} EQUAL -1)
	message(FATAL_ERROR "Driver ${DRIVER} does not exist, but you've set it as DRIVER.")
endif()
set(DRIVER_LINK_NAME can_${DRIVER})
message(STATUS "Using CAN driver ${DRIVER_LINK_NAME}")

if(${BUILD_ALL_DRIVERS})
	message(STATUS "Building all available drivers.")
endif()

## Driver end ##

if(${CMAKE_BUILD_TYPE} MATCHES "Release")
	message(STATUS "You are in release mode.")
else()
	if(${EXHAUSTIVE_DEBUGGING})
		add_definitions("-DEXHAUSTIVE_DEBUGGING")
		message(STATUS "Enabled exhaustive debugging.")
	else()
		message(STATUS "Enabled debugging.")
	endif()
endif()

message(STATUS "SDO response timeout is set to ${SDO_RESPONSE_TIMEOUT_MS}ms")
message(STATUS "Busname is set to ${BUSNAME} (only used by examples)")
message(STATUS "Baudrate is set to ${BAUDRATE} (only used by examples)")
message(STATUS "Pause between two consecutively sent CAN frames is set to ${CONSECUTIVE_SEND_PAUSE_MS}ms") 

message(STATUS "Found Boost headers in ${Boost_INCLUDE_DIRS}")
message(STATUS "Found Boost system library: ${Boost_SYSTEM_LIBRARY}")
message(STATUS "Found Boost filesystem library: ${Boost_FILESYSTEM_LIBRARY}")
message(STATUS "Found Threads library: ${CMAKE_THREAD_LIBS_INIT}")

find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)	
find_package(sensor_msgs REQUIRED)	
find_package(common REQUIRED)	
find_package(agv_msgs REQUIRED)	
find_package(agv_srvs REQUIRED)	
find_package(shared_parameters REQUIRED)

include_directories(SYSTEM 
	${rclcpp_INCLUDE_DIRS} 
	${sensor_msgs_INCLUDE_DIRS} 
	${agv_msgs_INCLUDE_DIRS}
	${agv_srvs_INCLUDE_DIRS}
	${common_INCLUDE_DIRS})

### Installation ###
macro(kacanopen_install)
	message(STATUS "Configuring installation for target(s) ${ARGV0}")

	install(TARGETS ${ARGV0}
  		RUNTIME DESTINATION lib/${PROJECT_NAME}
	)

	if (${ARGV1})
		install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/include
			DESTINATION ${CMAKE_INSTALL_PREFIX}
		)
	endif()
endmacro()

add_subdirectory(ros_bridge)
add_subdirectory(drivers_lgpl)
add_subdirectory(drivers)
add_subdirectory(core)
add_subdirectory(master)
add_subdirectory(apps)

ament_package()

install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/master/share/
	DESTINATION share/${PROJECT_NAME}/config
)